package com.yc.cloud.openai.portal.config;

import com.yc.cloud.common.basic.api.ResponseResult;
import io.netty.channel.ChannelOption;
import lombok.val;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(WebClient.Builder webClientBuilder) {
        HttpClient httpClient = HttpClient.create()
                // 设置连接超时时间
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 20000) // 连接超时为10秒
                //响应超时时间
                .responseTimeout(Duration.ofSeconds(30));
        return webClientBuilder
                .clientConnector(new ReactorClientHttpConnector(httpClient)) // 使用自定义的HttpClient
                .filter(errorHandlingFilter()) // 添加自定义错误处理过滤器
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(20 * 1024 * 1024)) // 设置缓冲区大小
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
    }

    private ExchangeFilterFunction errorHandlingFilter() {
        return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
            val status = clientResponse.statusCode();
            if (status.is4xxClientError()) {
                // 处理 4xx 错误
                return clientResponse.bodyToMono(String.class)
                        .flatMap(body -> Mono.error(new CustomWebClientException(ResponseResult.failed(status.value(), "请求参数错误"))));
            } else if (status.is5xxServerError()) {
                // 处理 5xx 错误
                return clientResponse.bodyToMono(String.class)
                        .flatMap(body -> Mono.error(new CustomWebClientException(ResponseResult.failed(status.value(), "服务暂时不可用: " + body))));
            } else if (status.is2xxSuccessful()) {
                // 正常成功的响应（2xx）直接返回
                return Mono.just(clientResponse);
            }
            return clientResponse.bodyToMono(String.class)
                    .flatMap(body -> Mono.error(new CustomWebClientException(ResponseResult.failed(status.value(), "服务暂时不可用: " + body))));
        });
    }

    // 自定义异常类，用于包装 ErrorResponse
    public static class CustomWebClientException extends RuntimeException {
        private final ResponseResult<String> errorResponse;

        public CustomWebClientException(ResponseResult<String> errorResponse) {
            super(errorResponse.getMessage());
            this.errorResponse = errorResponse;
        }

        public ResponseResult<String> getErrorResponse() {
            return errorResponse;
        }
    }
}

